import 'dart:async';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';
import '../../../../lib_basemodel/chat_room/kh_chat_room_seat_user_model.dart';
import '../../../../lib_basemodel/chat_room/kh_room_check_model.dart';
import '../../../../lib_basemodel/user/user.dart';
import '../../../../lib_baseview/utils/permission/permission_util.dart';
import '../../../../lib_baseview/widget/dialogs.dart';
import '../../../../lib_network/old/url_config.dart';
import '../../../../lib_runtime/logger.dart';
import '../../../../lib_user/user_manager.dart';
import '../../interface/room_page_model.dart';
import '../../socket/room_socket.dart';
import '../../template/mic_list/mic_waiting_list_page.dart';
import 'room_rtc_rtm.dart';

mixin RoomControllerMixin {
  /// 房间信令相关Token
  KHRoomCheckModel? roomTokenBean;

  // ValueNotifier<JoinChannelExtendRsp?> channelExt =
  //     ValueNotifier<JoinChannelExtendRsp?>(null);

  // ValueNotifier<bool> onMicNotifier = ValueNotifier<bool>(false);

  /// 当前正在说话的人
  ValueNotifier<Set<int>> speakers = ValueNotifier<Set<int>>({});

  // var doufengType = 0;

  // RidePush? ridePush;

  RoomSocket? roomSocket;
  RoomRtcRtm? roomRtcRtm;
  int followUid = 0;

  ///倒计时
  Timer? _timingTimer;

  RoomPageModel? roomPageModel;

  // SimpleChannelUserSlot? get meWithSlot => channel?.broadcaster
  //     .firstWhereOrNull((_) => _.user.id.toInt() == currUser?.id.toInt());

  // int get rid => channel?.channelId.toInt() ?? 0;

  /// 查找当前的用户是否在麦位上
  KhChatRoomSeatUserModel? get curUserOnMic =>
      roomPageModel?.roomEnterModel.micList
          ?.firstWhere(
            (mic) => mic?.micUser?.userId == currUser?.id,
            orElse: () => null,
          )
          ?.micUser;

  int get rid => 0;

  /// 当前
  /// 是否在麦上
  // bool get isOnMicSeat {
  //   return roomRtcRtm?.isBroadcaster ?? false;
  // }

  /// 是否在麦上
  bool get isOnMicSeat {
    return curUserOnMic != null;
  }

  /// 麦克风是否开启
  bool _isMicOn = false;
  bool get isMicOn => _isMicOn;
  set isMicOn(bool value) {
    _isMicOn = value;
  }

  /// 是否为虚拟麦
  // bool get isVirtualMic =>
  //     currUser?.id.toInt() == channel?.owner.id.toInt() &&
  //     (channel?.showRoomOwner ?? false);

  // bool get isVirtualMic => false;

  User? get currUser => UserManager.instance.currentUser;

  ///麦上是否有倒计时
  bool get hasTimingOnMic {
    bool hasTiming = false;
    // channel?.broadcaster.forEachIndexed((e, i) {
    //   if (e.hasUser()) {
    //     int timeNow = GlobalConfig.serverTime ~/ 1000;
    //     int time = e.counterTimestamp - timeNow;
    //     if (time > 0) {
    //       hasTiming = true;
    //     }
    //   }
    // });
    return hasTiming;
  }

  ///用户是否在麦上并且有倒计时
  bool userIsOnMicHasCount(int uid) {
    bool hasCount = false;
    // for (SimpleChannelUserSlot e in channel?.broadcaster ?? []) {
    //   if (e.hasUser() && e.user.id.toInt() == uid) {
    //     int timeNow = GlobalConfig.serverTime ~/ 1000;
    //     int time = e.counterTimestamp - timeNow;
    //     if (time > 0) {
    //       return true;
    //     }
    //   }
    // }
    return hasCount;
  }

  // SimpleChannelUserSlot? userOnMic(int? uid) {
  //   if (uid == null) return null;
  //   return channel?.broadcaster
  //       .firstWhereOrNull((element) => element.user.id.toInt() == uid);
  // }

  // ///如果麦上有倒计时 开始计时
  // startTimerIfNeed() {
  //   if (hasTimingOnMic) {
  //     _timingTimer ??= Timer.periodic(const Duration(seconds: 1), (Timer t) {
  //       cancelTimerIfNeed();
  //       notify();
  //     });
  //   }
  // }

  // cancelTimerIfNeed() {
  //   ///没有正在显示的倒计时 取消定时器停止刷新
  //   if (!hasTimingOnMic && _timingTimer != null) {
  //     RLog.d('cancelTimer');
  //     _timingTimer?.cancel();
  //     _timingTimer = null;
  //   }
  // }

  joinChannel(
      RoomPageModel
          roomPageModel /*JoinChannelRsp joinChannelRsp,
      {JoinSource? joinSource}*/
      ) {
    // RLog.d(
    //     'RoomController.joinChannel, oldId: ${channel?.channelId}, oldAgoraId: ${channel?.agoraChannelId}, newId: ${joinChannelRsp.channel.channelId}, newAgoraId: ${joinChannelRsp.channel.agoraChannelId}');

    // if (Platform.isAndroid)
    // FlutterCommon().startForeground(
    //     joinChannelRsp.channel.icon, joinChannelRsp.channel.title);

    // 是否复用长连接&rtc， 进同一个房间复用
    // var reuse = (channel?.channelId.toInt() ?? 0) > 0 &&
    //     channel?.channelId == joinChannelRsp.channel.channelId;

    roomTokenBean = roomPageModel.roomEnterModel.roomCheckBeanModel;

    if (roomTokenBean == null) {
      showToast('房间信令为空');
      return;
    }

    this.roomPageModel = roomPageModel;

    RtcConfig rtcConfig = RtcConfig(
      rtcToken: roomTokenBean?.rtcToken ?? '',
      rtmToken: roomTokenBean?.rtmToken ?? '',
      channelId: this.roomPageModel?.roomNumber ?? '',
    );
    roomRtcRtm = RoomRtcRtm(
      rtcConfig: rtcConfig,
      speakers: speakers,
    );

    _joinSocket(roomPageModel);
    _joinRtc();

    _joinRtm(roomRtcRtm);
    // onMic = isOnMicSeat;

    // if (!reuse) loadExt();

    // if (!reuse) RoomReporter.reportJoin(channel, joinSource: joinSource);
  }

  _joinSocket(RoomPageModel roomPageModel) {
    if (roomSocket != null) {
      roomSocket!.attachPageModel(roomPageModel);
    } else {
      roomSocket?.disconnect();
      roomSocket = RoomSocket(
          url: UrlConfig.wsDomain,
          channel: (roomTokenBean?.channel).toString(),
          roomModel: roomPageModel);
    }
  }

  _joinRtc({bool shouldReuse = false}) async {
    RLog.d('RoomController._joinRtc, rtc: $roomRtcRtm, reuse: $shouldReuse');

    // rtc已经初始化 & 进入的是同一房间，复用之前的rtc，直接return
    if (roomRtcRtm != null && shouldReuse) return;

    // roomRtc?.leaveChannel();

    await roomRtcRtm!.init();
    await roomRtcRtm!.joinRoom();

    // var micOpen = meWithSlot?.micStatus == MicStatus.OPEN;

    // if (micOpen) {
    //   var permissionStatus = await PermissionUtil.checkAndRequestPermissions(
    //       Get.context!, Permission.microphone);

    //   // 麦克风权限未授权，调用接口下麦
    //   if (permissionStatus != PermissionStatus.granted) {
    //     ChannelUpdate req = ChannelUpdate.create();
    //     req.channel = channel!.channelId;

    //     req.downMic = ChannelDownMic.create();
    //     RtcApi.instance.updateChannel(req);
    //   } /* else {
    //     await RtcManager.instance.changeRoleToBroadcaster();
    //   }*/
    // }
  }

  _joinRtm(RoomRtcRtm? rtm) async {
    await roomRtcRtm!.initRtm();

    if (rtm?.rtcConfig.rtmToken == null) return;
    await roomRtcRtm!.loginRtm(rtm!.rtcConfig.rtmToken);

    // RtcConfig rtcConfig = RtcConfig(
    //   rtcToken: roomTokenBean?.rtcToken ?? '',
    //   rtmToken: roomTokenBean?.rtmToken ?? '',
    //   channelId: (roomTokenBean?.channel ?? 0).toString(),
    // );
    // roomRtc = RoomRtc(
    //   rtcConfig: rtcConfig,
    //   speakers: speakers,
    // );

    // // roomRtc?.leaveChannel();

    // await roomRtc!.init();
    // await roomRtc!.joinRoom();
  }

  void _initChannelExt() {
    // channelExt = JoinChannelExtendRsp()..gameInfo = channel.gameInfo;
  }

  // Future<BaseRspResult<JoinChannelExtendRsp>?> loadExt() async {
  //   var rid = channel?.channelId.toInt() ?? 0;
  //   if (rid <= 0) return null;

  //   var rsp = await handleRsp(() => RtcApi.getExtInfo(rid), showLoading: false);
  //   if (rsp.isSuccess) {
  //     channelExt.value = rsp.data;
  //   }
  //   notify();
  //   return rsp;
  // }

  /// 是否连上房间
  bool get inRoom => false;

  /// 点麦位申请上麦
  void joinMicWithPosition(BuildContext context, int position) async {
    showToast("点麦位申请上麦");

    // if (await PermissionUtil.checkAndRequestPermissions(
    //         context, Permission.microphone) !=
    //     PermissionStatus.granted) {
    //   return;
    // }

    // ChannelUpdate req = ChannelUpdate.create();
    // req.channel = channel!.channelId;

    // /// freePub 是否是自由上麦
    // if (!channel!.freePub) {
    //   if (channel!.role == RtcUserRole.Receptionist ||
    //       channel!.role == RtcUserRole.Owner ||
    //       channel!.role == RtcUserRole.Manager) {
    //     //上接待管理员位
    //     req.upMic = ChannelUpMic.create()
    //       ..position = position
    //       ..mode = UpMicMode.FIX_POSITION_MIC;
    //   } else {
    //     openMicWaitingListPage(context);
    //     return;
    //   }
    // } else {
    //   //上接待管理员位
    //   req.upMic = ChannelUpMic.create()
    //     ..position = position
    //     ..mode = UpMicMode.FIX_POSITION_MIC;
    // }
    // var result = await RtcApi.instance.updateChannel(req);
    // if (result.isSuccess) {
    // } else {
    //   showToast(result.errorMsg ?? "");
    // }
  }

  openMicWaitingListPage(BuildContext context) {
    _openModalBottomSheet(context, (context) => MicWaitingListPage());
  }

  _openModalBottomSheet(BuildContext context, WidgetBuilder builder) {
    showModalBottomSheet(
      shape: const RoundedRectangleBorder(
        borderRadius: BorderRadiusDirectional.only(
          topStart: Radius.circular(24),
          topEnd: Radius.circular(24),
        ),
      ),
      context: context,
      builder: builder,
    );
  }

  Future<void> openMic() async {
    // 申请麦克风权限
    var permissionStatus = await PermissionUtil.checkAndRequestPermissions(
        Get.context!, Permission.microphone);
    if (permissionStatus != PermissionStatus.granted) {
      RLog.d('Open mic with permission not granted, ignore!!!');
      return;
    }

    await roomRtcRtm?.openMic();
    notify();
  }

  Future<void> closeMic() async {
    await roomRtcRtm?.closeMic();
    notify();

    // ChannelUpdate req = ChannelUpdate.create();
    // req.channel = channel!.channelId;
    // req.closeMic = ChannelCloseMic.create();

    // var result = await handleRsp(() => RtcApi.instance.updateChannel(req));
    // RLog.d('Close mic with result: ${result.isSuccess}');
    // if (result.isSuccess) {
    //   channel?.broadcaster
    //       .firstWhere(
    //           (element) => element.user.id.toInt() == currUser?.id.toInt(),
    //           orElse: () => SimpleChannelUserSlot.create())
    //       .micStatus = MicStatus.CLOSE;
    //   await roomRtc!.closeMic();
    //   notify();
    // }
  }

  /// socket 发送公屏消息
  // void sendChatMsg(message_api.SendToRoomReq msgData) async {
  //   try {
  //     // roomSocket?.sendChatMsg(msgData);
  //     BaseRspResult result = await MessageCheckApi.instance.sendToRoom(msgData);
  //     if (!result.isSuccess) {
  //       showToast(result.errorMsg ?? T.current!.send_fail);
  //     }
  //     Reporter.track(TrackEvent.publicScreenChat, {
  //       "rid": channel?.channelId.toInt(),
  //       "room_type": channel?.roomTypeObj.type,
  //       "channel_type": channel?.roomLabel,
  //       "use_type": channel?.usage,
  //       "is_work": channel?.inProcessOfSchedule,
  //       "owner_uid": channel?.owner.id.toInt(),
  //     });
  //   } catch (e) {
  //     RLog.d("SocketMsg error $e");
  //   }
  // }

  void leaveChannel() {
    // RLog.d('RoomController.leaveChannel, id: ${channel?.channelId}');
    // RoomReporter.reportExit(channel);
    // onMic = false;
    // isOnMicSeat
    isMicOn = false;

    // roomSocket?.disconnect();
    // roomSocket = null;

    // roomRtc?.leaveChannel();
    // roomRtc = null;

    // channelExt.value = null;
    // channel = null;
    // token = null;
    // rtmToken = null;
    // wsUrl = null;
    // ridePush = null;
    // roomPageModel = null;
    // doufengType = 0;

    // MessageNotifierListenerRidePush.rideCounter = null;
    // _timingTimer?.cancel();
    // _timingTimer = null;
    // CacheUtil.removeObject(CacheKeys.carListCacheKey);
    // if (Platform.isAndroid) FlutterCommon().stopForeground();
  }

  // set onMic(bool value) {
  //   if (onMicNotifier.value == value) return;

  //   onMicNotifier.value = value;
  // }

  void notify();

  ///麦位的key 获取麦位坐标
  // final List<GlobalKey> _positionKeys = [];
  // GlobalKey getPositionGlobalKey(int index) {
  //   while(index >= _positionKeys.length){
  //     _positionKeys.add(GlobalKey());
  //   }
  //   return _positionKeys[index];
  // }
  final Map<int, GlobalKey> _micUidKeys = {};
  GlobalKey getMicGlobalKey(int uid) {
    if (_micUidKeys.containsKey(uid)) {
      return _micUidKeys[uid]!;
    }
    _micUidKeys[uid] = GlobalKey();
    return _micUidKeys[uid]!;
  }

  removeUnUseMicKey() {
    // List<int> list =
    //     channel?.broadcaster.map((e) => e.user.id.toInt()).toList() ?? [];
    // _micUidKeys.removeWhere((key, value) => list.contains(key) == false);
    // RLog.d('_micUidKeys:$_micUidKeys  $list');
  }

  // PositionOffset getPointByUid(int uid) {
  //   UserIconStyle defaultStyle = UserIconStyle.normal;
  //   Size defaultSize = RoomConfig.micIconSize(defaultStyle);
  //   SimpleChannelUserSlot? userSlot;
  //   int index = channel?.broadcaster.indexWhere(
  //           (element) => element.user.id.toInt() == uid && uid > 0) ??
  //       -1;
  //   if (index >= 0) {
  //     userSlot = channel?.broadcaster[index];
  //   }
  //   try {
  //     if (userSlot != null && _micUidKeys.containsKey(uid)) {
  //       final RenderBox box =
  //           _micUidKeys[uid]!.currentContext?.findRenderObject() as RenderBox;
  //       Offset offset = box.localToGlobal(const Offset(0.0, 0.0));
  //       if (offset.dx >= 0 && offset.dx <= ScreenUtils.ins.screenWidth) {
  //         return PositionOffset(offset, defaultStyle, box.size);
  //       }
  //     }
  //   } catch (e) {
  //     RLog.d(e.toString());
  //   }
  //   return PositionOffset(Offset(ScreenUtils.ins.screenWidth - 70.0, 50.0),
  //       defaultStyle, defaultSize, false);
  // }
}
